#include <iostream>

template <typename T>
class smartPtr
{
public:
    smartPtr(T *p) : m_p(p), m_count(new size_t) {}

    ~smartPtr() { decrease(); }

    smartPtr(const smartPtr &other) : m_p(other.m_p), m_count(other.m_count)
    {
        increase();
    }

    smartPtr &operator=(const smartPtr &other)
    {
        // 避免自赋值
        if (m_p != other.m_p)
        {
            decrease();
            m_p = other.m_p;
            increase();
        }
        return *this;
    }
    // 注意对->的重载返回值是裸原始指针，C++规定了->使用有多层次深入递进关系，指向的是最深那层的对象
    T *operator->() const
    {
        return m_p;
    }
    T &operator*() const
    {
        return *m_p;
    }

private:
    void decrease()
    {
        if (--(*m_count) == 0)
        {
            delete m_p;
            delete m_count;
        }
            
    }
    void increase()
    {
        ++(*m_count);
    }
private:
    T *m_p;
    size_t *m_count;
};
